home *** CD-ROM | disk | FTP | other *** search
-
- ; Listing2a.s - Dieses Programm registriert im Byte "Zaehler", wie
- ; oft die rechte Maustaste gedrückt wurde, oder, besser noch, wie lange
- ; sie gedrückt wurde, denn wenn sie gedrückt bleibt, zählt der Zähler
- ; trotzdem weiter, um auszusteigen linke Maustaste
-
- Anfang:
- btst #2,$dff016 ; POTINP - rechte Maustaste gedrückt?
- beq.s Dazu ; Wenn ja, springe zu Dazu
- btst #6,$bfe001 ; Linke Maustaste gedrückt?
- bne.s Anfang ; Wenn nicht, springe zu Anfang zurück
- rts ; Wenn hingegen ja, dann steige aus!
-
- Dazu:
- move.b Zaehler,$dff180 ; Gib den Wert von Zaehler in Farbe 0
- ; (COLOR0)
- addq.b #1,Zaehler ; Inkrementiere Zaehler um 1 (zählt 1 dazu)
- bra.s Anfang ; Springe (immer) zu Anfang zurück
-
- Zaehler:
- dc.b 0 ; Dieses Byte ist unser Zähler
-
- END ; Mit END wird das Ende des Listings
- ; markiert, alles, was folgt, wird vom
- ; Assembler nicht mehre interpretiert
-
- Bemerke: POTINP ist der Name des Registers $dff016. Der (großgeschriebene)
- Name nach dem Strichpunkt bezieht sich immer auf ein $dffxxx-
- Register.
-
- In diesem Beispielprogramm erkennt man die Verwendung der Label sei es als
- Kennzeichnung von Befehlen (bne.s Anfang, bra.s Anfang...), wie auch um
- Bytes anzusprechen (addq.b #1,Zaehler). Es besteht kein Unterschied
- zwischen der Label Anfang und der Label Zaehler: beides sind Label, also
- NAMEN, DIE EINEN BESTIMMTEN PUNKT IM SPEICHER MARKIEREN, OB ES NUN EIN
- BYTE ODER EINE REIHE VON BEFEHLEN ODER SONST ETWAS IST. DAMIT KANN MAN DIE
- BEFEHLE UNTER DEM LABEL AUSFÜHREN ODER AUCH NUR DAS BYTE NACH DEM LABEL
- VERÄNDERN. Ich habe bemerkt, daß es vielen Schwierigkeiten bereitet, sich
- mit dieser Logik vertraut zu machen. Machen wir einige Beispiele um die
- Rolle der Labels genauer zu verstehen: stellt euch vor, ihr habt einen
- kleinen Schrebergarten, der eingezäunt ist, und in dessen Mitte verläuft
- ein kleiner Weg. Nachdem ihr ihn umgegraben habt, beschließt ihr
- Erdbeeren, Kohl, Rüben und Petersilie zu pflanzen, also teilt ihr ihn in
- vier gleich große Rechtecke ein und streut den Samen aus. Um zu wissen, wo
- das verschiedenen Grünzeug wächst, verwendet man meistens solche
- Plastiktäfelchen mit einem Spitz unten dran, auf dem ein Foto der
- Erdbeere/Kohl... ist. Man steckt sie dann in die Erde, ihr kennt die
- Dinger doch..? Also pflanzen wir sie: Auf einem Täfelchen steht
- ERDBEEREN:, auf dem anderen KOHL:, dem nächsten RUEBEN: und dem letzten
- PETERSILIE:. Wir haben die Etiketten so in die Erde gesteckt, daß sie
- jeweils den ANFANG des abgebildeten Gemüses markieren, und somit zugleich
- das ENDE des vorherigen.
-
- ERDBEEREN: KOHL: RUEBEN: PETERSILIE:
- \/ \/ \/ \/
- ..................oooooooooooooooooo^^^^^^^^^^^^^^^^^^-_-_-_-_-_-_-_-_-_
-
-
- Wenn wir die "...." als Erdbeeren ansehen, den Kohl als "oooo", die Rüben
- als "^^^^" und die Petersilie als "-_-_", dann wird ein "BNE KOHL" soviel
- bedeuten wie "GEHE ZUR ETIKETTE KOHL:", und nicht "renn´ mitten ins Beet
- hinein", oder "gehe in Richtung KOHL:". Einzi und allein "GEHE ZUM
- TÄFELCHEN MIT DER AUFSCHRIFT KOHL: UND FÜHRE DIE BEFEHLE, DIE FOLGEN,
- AUS", in diesem Fall werden wir die "oooo" ausführen. Wenn das Label so
- verwendet wird:
-
- addq.b #1,RUEBEN
-
- Da tun wir nichts anderes als einen Samen im ersten Byte nach der Etikette
- dazuzufügen, es ändert aber nicht seine Funktion! Es bedeutet nicht
- Inhalte oder andere komische Dinge!!! Es markiert immer einen Punkt im
- Speicher, also des Listings, das in unserem Fall der Anfang der Rüben ist.
- Probieren wir mal, ein MOVE.B ERDBEEREN,RUEBEN zu machen:
-
- ERDBEEREN: KOHL: RUEBEN: PETERSILIE:
- \/ \/ \/ \/
- ..................oooooooooooooooooo.^^^^^^^^^^^^^^^^^-_-_-_-_-_-_-_-_-_
-
- | |
- \------->--------->-------->------>
-
- Wie ihr seht, ist ein ".", also das Byte nach ERDBEEREN:, ins Byte nach
- RUEBEN: kopiert worden. Versuchen wir nun ein MOVE.W KOHL,ERDBEEREN
-
- ERDBEEREN: KOHL: RUEBEN: PETERSILIE:
- \/ \/ \/ \/
- oo................oooooooooooooooooo^^^^^^^^^^^^^^^^^^-_-_-_-_-_-_-_-_-_
-
- || ||
- \<----<----<-----/
-
- Wir haben die ersten zwei "oo", die sich nach KOHL: befanden, in die
- ersten zwei Bytes nahc ERDBEEREN: kopiert.
-
- Wenn man einen Punkt zwischen zwei Labels lesen/scheiben möchte, dann
- brauchtr man nur ein weiteres hinzufügen: um 4 Bytes Kohl mitten in die
- Rüben zu geben, werden wir in der Mitte der Rüben ein neues Label namens
- RUE2: pflanzen, und danach ein MOVE.L KOHL,RUE2
-
- Vorher:
-
- ERDBEEREN: KOHL: RUEBEN: RUE2: PETERSILIE:
- \/ \/ \/ \/ \/
- ..................oooooooooooooooooo^^^^^^^^^^^^^^^^^^-_-_-_-_-_-_-_-_-_
-
- Nachher:
-
- ERDBEEREN: KOHL: RUEBEN: RUE2: PETERSILIE:
- \/ \/ \/ \/ \/
- ..................oooooooooooooooooo^^^^^^^^oooo^^^^^^-_-_-_-_-_-_-_-_-_
- |||| ||||
- \\\\ ---->---->----->-- ////
-
- Wir haben die ersten 4 Bytes von KOHL: in die ersten 4 Bytes nach RUE2:
- kopiet. Das .L bedeutet eben 4 Bytes...
-
- Es funktioniert auf die gleiche Art und Weise, als wenn man die realen
- Adressen verwenden würde, wie schon in LEKTION1 erklärt (WORT
- PEDAL>PORTAL), nur daß anstatt mit den Adressen, bei denen jeder Samen
- eine eigene hat, mit Etiketten, also Labels, gearbeitet wird. Unter
- Verwendung der Adressen:
-
- ERDBEEREN: KOHL: RUEBEN: PETERSILIE:
- \/ \/ \/ \/
- ..................oooooooooooooooooo^^^^^^^^^^^^^^^^^^-_-_-_-_-_-_-_-_-_
- 123456789012345678901234567890123456789012345678901234567890123456789012
- 111111111122222222223333333333444444444455555555556666666666777
-
- Wenn man mit Adressen arbeitet, kann man 4 Bytes von jeder Stelle an jede
- Stelle kopieren, z.B. von Stelle 25 zu Stelle 60: Move.L 25,60
-
- ERDBEEREN: KOHL: RUEBEN: PETERSILIE:
- \/ \/ \/ \/
- ..................oooooooooooooooooo^^^^^^^^^^^^^^^^^^-_-_-oooo_-_-_-_-_
- 123456789012345678901234567890123456789012345678901234567890123456789012
- 111111111122222222223333333333444444444455555555556666666666777
- |||| ||||
- \\\\ --->---->---->---->--->---> ////
-
- Die gleiche Operation läßt sich aber auch durchführen, indem man ein Label
- an Position 25 und eines an Position 60 gibt:
-
- Label1: Label2:
- \/ \/
- ..................oooooooooooooooooo^^^^^^^^^^^^^^^^^^-_-_-oooo_-_-_-_-_
- |||| ||||
- \\\\ --->---->---->---->--->---> ////
-
- Wieso man Labels den Adressen vorgezogen hat? GANZ EINFACH! Wenn wir
- Adressen verwendet hätten, und zwischen dem Kohl und den Rüben etwas
- eingefügt hätten, dann wäre die Adresse nicht mehr 60 gewesen, aber irgend
- eine andere Zahl, z.B. 80, und wir hätten alle Adressen ändern müßen,
- indem wir sie "nach vorne" schieben, um das Stück reinzupassen. Mit den
- Labels hingegen macht uns ein Stück mehr oder weniger dazwischen nichts
- aus, da der Assembler erst beim Assemblieren die realen Adressen zuteilt.
-
- Probiert dieses Programm auszuführen, das erste Mal ohne den Mausknopf zu
- drücken, nur die linke Taste zum Aussteigen: das Byte ZAEHLER ist in
- diesem Fall 0 geblieben, wie man einfach mit dem Befehl M sehen kann.
- Dieser Befehl zeigt die effektiven Werte in den Speicherzellen byteweise
- an. Aufgerufen wird er z.B. mit M $50000 oder M Label: wir werden M
- Zaehler tippen, und 0 erhalten, gefolgt von anderen Zahlen, die die
- folgenden Bytes darstellen, uns aber nicht interessieren. Um im Speicher
- voran zu kommen, drückt öfters RETURN, um auszusteigen, ESC. Die Bytes
- werden natürlich in Hexadezimal angezeigt. Assembliert von neuem mit A und
- drückt diesmal einige Male die rechte Maustaste, bevor ihr aussteigt (mit
- der linken Taste): wenn ihr jetzt M Zaehler eingebt, werdet ihr eine Zahl
- verschieden von 0 erhalten, der der Anzahl der Zyklen entspricht, in denen
- die Maustaste gedrückt war. Diese Zyklen werden vom Prozessor sehr schnell
- ausgeführt, und auch wenn ihr nur einen Augenblick lang die rechte Taste
- drückt, werdet ihr eine Zaahl größer als eins erhalten. Es ist zu
- beachten, daß der Zähler ein Byte groß ist, also einen Maximalwert von
- $FF, also 255 oder %11111111 erreichen kann, danach startet er wieder von
- 0 (wenn man mit dem dazuzählen fortfährt). $FF+1=0, $ff+2=1... Die
- Evolution dieses Programmes gegenüber dem vorherigen ist die etwas
- komplexere Struktur der bedingten Sprünge, und ich rate euch, ja nicht
- fortzufahren, bis ihr das nicht verstanden habt! Weiters wird ein Byte als
- Variable verwendet. Diese Byte, Zaehler genannt, wird nicht nur
- beschrieben, sondern auch gelesen, um dessen Wert in das Register $dff180,
- Color0, einzutragen. Jetzt beginnt man zu verstehen, wie es einem Programm
- möglich ist, verschiedene Werte zu speichern, die von Nutzen sind, wie
- etwa die Leben von Player1, seine energie, seine Punkte, etc. Die
- Verwendung von Labels ist dem Programmierer nützlich, das Programm selbst
- aber, einmal assembliert, wird nur eine Serie von Bytes werden, die der
- 68000er lesen kann. Sie werden als Befehle interpretiert, die sich auf
- eine direkte Adresse beziehen: um das bestätigt zu bekommen, assembliert
- das Programm und macht ein D Anfang... So wird das Programm sichtbat, wie
- es in Wirklichkeit ist: an Stelle der Label finden wir die EFFEKTIVEN
- Adressen. Die erste Zahlenkolonne links sind die realen Adressen, die wir
- gerade lesen, die zweite Kolonne zeigt die Befehle in ihrer REALEN Form,
- also eine reine Bytesequenz (z.B. wird die erste Zeile BTST #2,$dff016 im
- Speicher so aussehen: 0839000200dff016, wobei $0839 BTST bedeutet, 0002
- ist das #2, 00dff016 ist die angesprochene Adresse), die dritte Kolonne
- ist die disassemblierte Form der Befehle. Das ist genau das Gegenteil des
- Assemblierens: hier werden die Bytes in Befehle wie Add, Move u.ä.
- umgewandelt. Um zu Beweisen, daß die Befehle ganz bestimmte Zahlenfolgen
- werden, tauscht die erste Zeile folgendermaßen aus:
-
- btst #2,$dff016 ; POTINP - rechte Maustaste gedrückt?
-
- Ersetzen durch:
-
- dc.l $08390002,$00dff016
-
- oder:
-
- dc.w $0839,$0002,$00df,$f016
-
- oder:
-
- dc.b $08,$39,$00,$02,$00,$df,$f0,$16
-
-
- In allen Fällen ist das Resultat 0839000200dff016 im Speicher, was vom
- 68000 als "btst #2,$dff016" interpretiert wird, also "ist Bit 2 von
- $dff016 Null?".
-
- Wenn die Variabel ein Word anstatt ein Byte wäre, würde das Programm
- folgendermaßen aussehen:
-
- Anfang:
- btst #2,$dff016 ; POTINP - rechte Maustaste gedrückt?
- beq.s Dazu ; Wenn ja, springe zu Dazu
- btst #6,$bfe001 ; Linke Maustaste gedrückt?
- bne.s Anfang ; Wenn nicht, springe zu Anfang zurück
- rts ; Wenn hingegen ja, dann steige aus!
-
- Dazu:
- move.w Zaehler,$dff180 ; Farbe 0 - Ein .W beim move verwenden!
- ; (COLOR0)
- addq.w #1,Zaehler ; ADDQ.W statt ADDQ.b!!!
- bra.s Anfang ; Springe (immer) zu Anfang zurück
-
- Zaehler:
- dc.w 0 ; Dieses Byte ist unser Zähler
-
-
- Da der Zähler nun ein Word groß ist, kann er maximal 65535 enthalten, das
- entspricht $FFFF oder %1111111111111111.
-
- Wenn wir ein Longword als Zaehler verwenden würden, dann hätte $FFFFFFFF
- Platz, also ein paar Miliarden, bevor er wieder auf 0 springen würde. Es
- ist aber aufzupassen, denn das höchstwertigste Bit (also das 31. im Falle
- eines Longword) wird als Vorzeichen verwendet: probiert ein ?0FFFFFFF, ihr
- werdet 268 Millionen und ein paar zerquetschte erhalten, und in Binärform
- sind die vier höchsten Bit (also die ersten vier nach dem %) auf 0. Die
- höchste Zahl die man erreichen kann, ist $7FFFFFFF, oder binär:
-
- ;10987654321098765432109876543210 ; Bitzahl von 0 bis 31
- %01111111111111111111111111111111
-
- Das Bit Nr. 31 (was das zweiundreisigste wäre, es zählt aber auch di NULL)
- ist auf 0, während alle anderen auf 1 sind. Wenn man nun ein ?$7FFFFFFF+1
- macht, erhält man -2 Milliarden und Etwas, und destomehr man die Ziffer
- erhöht, desto mehr nähert man sich der 0, in der Tat erhält man mit ?-1
- $FFFFFFFF, mit $-2 = $FFFFFFE.
-
- Dieses System des höchsten Bits, das als Vorzeichen wirkt, kann auch für
- Bytes und Words gelten: ein MOVE.B #-1,$50000 kann auch als MOVE.B
- #FF,$50000 geschrieben werden. Das größtmögliche Byte würde also
- %01111111, also $7F-> 127, für das Word gilt das gleiche,
- %0111111111111111 -> $7FFF, also 32767. Aber es hängt davon ab, wie man
- das Programm schreibt, ob man nun die Zahlen als positive und negative
- ansieht oder absolut.
-
- Probiert, das Listing so abzuändern, daß Zaehler: ein Word wird, wie oben
- beschrieben: ihr könnt die Editorfunktionen des ASMONE "AUSCHNEIDEN und
- EINFÜGEN" verwenden. Damit könnt ihr ein Stück Text "ausschneiden" und
- irgendwo anders "aufkleben", also "einfügen". Dafür verwendet die Tasten
- Amiga_rechts+b um den Anfang des Blockes zu markieren, den ihr
- ausschneiden wollt; in diesem Fall wählt den Teil am Anfang des
- modifizierten Listings aus, gleich nach dem "...folgendermaßen aussehen:".
- Positioniert den Cursor eben über der Label Anfang: und drückt
- Amiga_rechts+b. Nun könnt ihr den Block auswählen, der in negativ
- erscheinen wird, indme ihr einfach mit den Pfeiltasten rauf und runter
- fahrt. Unter dem dc.w 0 angekommen, drückt Amiga+c, und das Stück Text,
- das nun das Listing beinhaltet, wandert in den Speicher. Nun geht zum
- Anfang des Listings, durch Pfeil_rauf+SHIFT, und drückt Amiga+i... Wie von
- Zauberhand erscheint eine Kopie des Textes, den ihr vorhin ausgewählt
- habt. Nun müßt ihr nur noch ein END unter dem dc.w 0 setzen, einige
- Leerzeichen vom limken Rand entfernt, besser noch ein TAB, um das orginale
- Listing auszuschließen, das ja noch den Zaehler: mit dem Byte enthält.
- Assembliert und Jumpt (startet es...).
-
- P.S: Ignoriert die Zahlen, die nach jeden "J" auftauchen, einfach.
- Sie werden später erklärt.
-
- Sofort werdet ihr einen Unterschied beim Aufleuchten des Bildschirmes
- feststellen, wenn ihr die rechte Maustaste drückt; macht ein M Zaehler,
- und kontrolliert den Inhalt. Jetzt ist es ein Word, also werden jetzt die
- ersten zwei Zahlen gültig sein, also die ersten zwei Bytes. Wenn z.B. ein
- 00 30 erscheint, dann wird das bedeuten, daß das ADDQ.W #1,Zaehler $30 Mal
- ausgeführt worden ist, also 48 Mal (in Dezimal). Bei einem 02 5e $25e mal,
- das entspricht (?$25e) 606 Mal.
-
- Wenn ihr keine Experten im "Ausschneiden und Einfügen" (Cut & Paste) seid,
- dann übt ein bißchen, indem ihr Textteile von einem Punkt zum anderen
- kopiert. Beachtet auch, daß wenn ein mit Amiga_rechts+b ausgewählter Text
- anstatt mit Amiga_c mit Amiga_x traktiert wird, gelöscht wird, mit Amiga_i
- aber irgendwo anders eingefügt werden kann. Ich versichere euch,
- programmieren ist das reinste Ausschneiden und Einfügen, da dieser Trick
- dir das Neuschreiben von ähnlichen Programmteilen erspart, die nur kopiert
- und leicht verändert werden müßen.
-
- Auch mit den Binärzahlen sollte man sich vertraut machen, denn auch viele
- Hardware-Register sind BITMAPPED, d.h. jedes Bit hat eine Bedeutung. Hier
- eine Tabelle, um den Unterschied klarzumachen:
-
-
-
- Hexadezimal Binär Dezimal
- 0 %00000 0
- 1 %00001 1
- 2 %00010 2
- 3 %00011 3
- 4 %00100 4
- 5 %00101 5
- 6 %00110 6
- 7 %00111 7
- 8 %01000 8
- 9 %01001 9
- $A %01010 10
- $B %01011 11
- $C %01100 12
- $D %01101 13
- $E %01110 14
- $F %01111 15
- $10 %10000 16
- $11 %10001 17
- $12 %10010 18
- ... ... ...
-
- Wie ihr seht, folgt das Binärsystem einer einfachen Logik, die die Zahl
- mit einsen füllt, bis sie zu einer 11, 111, 1111 etc. gekommen ist: nach
- einem %011 kommt es zu einem %100, nach einem %0111 zu einem %1000, nach
- einem %01111 zu einem %10000 usw. Ich erinnere euch, daß Hexzahlen von
- einem $-Zeiche vorangegangen werden, die Binärzahlen von einem %. Die
- Zahlen in Dezimalformat hingegen stehen ohne nicht vorne dran. Wenn wir 9
- oder $9 schreiben, meinen wir immer 9, aber es besteht ein großer
- Unterschied zwischen $10 und 10!!! Denn 10 ist 10, $10 in Hex ist 16 in
- Dezimal! Einfacher ausgedrückt, nach dem 9 ändert ein $ mehr oder weiniger
- alles. Man muß die Zahlen nicht im Kopf konvertieren können, dafür gibt´s
- ja den "?"-Befehl im ASMONE, der das REsultat in jedem Format ausgibt,
- Dezimal, Hexadezimal, Binär und ASCII, also in Form von Charaktern. Denn
- Charakter wie "abcd.." sind nichts anderes als Bytes, die nach dem
- ASCII-Standart zugewiesen sind. So ist ein "a"=$61, während ein "A" ein
- $41 ist. Es ist leicht mit einem ?"a" oder einem ?$61 in der Kommandozeile
- nachgewiesen.
-
- Bemerke: Das .s am BNE bedeutet SHORT, also Kurz (equivalent zu .b), im
- Gegenteil zu .w, wenn das Label "weit" weg ist. Probiert einfach immer ein
- .s zu setzen, und wenn das Label nach dem beq oder bne... zu weit weg ist
- (mehr als 127 Byte), dann korrigiert es der Assembler mit .w automatisch.
- Um das zu testen, probiert folgende Änderung:
-
-
- Anfang:
- btst #2,$dff016 ; POTINP - rechte Maustaste gedrückt?
- beq.s Dazu ; Wenn ja, springe zu Dazu
- btst #6,$bfe001 ; Linke Maustaste gedrückt?
- bne.s Anfang ; Wenn nicht, springe zu Anfang zurück
- rts ; Wenn hingegen ja, dann steige aus!
-
- dcb.b 200,0 ; Dieser Befehl wird später erklärt, hier
- ; werden einfach 200 bytes $00 im Speicher
- ; zwischen dem RTS und der Label Dazu: eingefügt,
- ; um die Distanz zu vergrößern.
-
- Dazu:
- move.b Zaehler,$dff180 ; Gib den Wert von Zaehler in Farbe 0
- ; (COLOR0)
- addq.b #1,Zaehler ; Inkrementiere Zaehler um 1 (zählt 1 dazu)
- bra.s Anfang ; Springe (immer) zu Anfang zurück
-
- Zaehler:
- dc.b 0 ; Dieses Byte ist unser Zähler
-
-
- Beim Assemblieren werdet ihr bemerken, daß der Assembler ein FORCED TO
- WORD SIZE meldet. Das bedeutet, er hat das bne.s zu einem bne.w gezwungen,
- weil die aufgerufene Routine zu weit weg war. Ich rate euch, immer ein .s
- nach einem BRS, BNE, BRA, BEQ und ähnlichem zu setzen, wenn es nicht
- stimmt, korrigiert es ja der Assembler. Man kann auch immer ein .w setzen,
- aber die .s sind schneller und verbrauchen weniger Bytes im Speicher. Um
- das Konzept der Label nochmal aufzugreifen: das dcb.b 200,0 ist ein
- Paradebeispiel dafür, wie nützlich die Label sind, die uns davor bewahrt
- haben, die nachfolgenden Adressen alle neuzuschreiben, indem man sie alle
- um 200 Bytes aufstocken hätte müßen.
-
-